package com.wantup.demo01;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * @author Zhaoluowei
 * @version 1.0
 * @date 2019/6/27 14:29
 * <p>
 * 线程分支合并框架
 * <p>
 * 工作窃取
 */
public class TestForkJoinPool {

    public static void main(String[] args) {
//        ForkJoinPool joinPool = new ForkJoinPool();
//
//        ForkJoinTask<Long> calculate = new ForkJoinSumCalculate(0L, 100000000L);
//        Long invoke = joinPool.invoke(calculate);
//        System.out.println(invoke);


        test();

    }


    public static void test() {
        long sum = 0L;
        Instant start = Instant.now();

        for (long i = 0L; i <= 100000000L; i++) {
            sum += i;
        }
        Instant end = Instant.now();
        System.out.println("计算结果为 : " + sum);
        System.out.println("共耗时 : " + Duration.between(start, end).toMillis());

    }


}

/**
 * RecursiveAction  没有返回值
 * RecursiveTask 有返回值
 */
class ForkJoinSumCalculate extends RecursiveTask<Long> {

    private long start;
    private long end;

    private static final long THURSHOLD = 0L;

    public ForkJoinSumCalculate(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        long length = end - start;
        if (length <= THURSHOLD) {
            long sum = 0L;
            for (long i = start; i <= end; i++) {
                sum += i;
            }

            return sum;
        } else {
            long middle = (start + end) / 2;
            ForkJoinSumCalculate left = new ForkJoinSumCalculate(start, middle);
            left.fork();//进行拆分 压入线程队列。

            ForkJoinSumCalculate right = new ForkJoinSumCalculate(middle + 1, end);
            right.fork();

            return left.join() + right.join();
        }

    }
}
